﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data.Objects;
using System.Data.Metadata.Edm;
using System.Data;
using QLBH.DataModel;

namespace QLBH.Model.Controller
{
    public interface IGenericRepository<T> where T : class
    {
        IQueryable<T> GetAll();
        IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
        T Add(T entity);
        void Delete(T entity);
        void Deletes(IList<T> entities);
        void Delete(Expression<Func<T, bool>> predicate);
        T Edit(T entity);
        void Save();
    }

    public abstract class GenericRepository<C, T> :IGenericRepository<T>
        where T : class
        where C : ObjectContext, new()
    {        
        private C _entities = new C();
        public C Context
        {

            get { return _entities; }
            set { _entities = value; }
        }

        public virtual IQueryable<T> GetAll()
        {
            try
            {                
                IQueryable<T> query = _entities.CreateObjectSet<T>();
                return query;
            }
            catch (System.Exception ex)
            {
                throw ex;
            }

        }

        public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            try
            {
                IQueryable<T> query = _entities.CreateObjectSet<T>().Where(predicate);
                return query;
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
            
        }

        public virtual T Add(T entity)
        {
            try
            {
                _entities.CreateObjectSet<T>().AddObject(entity);
                Save();                
                return entity;
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
            
        }
        public virtual void Delete(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            try
            {
                IQueryable<T> result = FindBy(predicate);
                ObjectSet<T> objSet = _entities.CreateObjectSet<T>();
                
                foreach (T entity in result)
                {
                    T var = objSet.ApplyCurrentValues(entity);
                    objSet.DeleteObject(var);
                }

               // Save();
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
            
        }

        public virtual void Delete(T entity)
        {
            try
            {
                ObjectSet<T> objSet = _entities.CreateObjectSet<T>();
                T var = objSet.ApplyCurrentValues(entity);
                objSet.DeleteObject(var);
                Save();
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
            
        }
        public virtual void Deletes(IList<T> entities)
        {
            try
            {
                foreach (T entity in entities)
                {
                    ObjectSet<T> objSet = _entities.CreateObjectSet<T>();
                    T var=objSet.ApplyCurrentValues(entity);
                    objSet.DeleteObject(var);
                }
                Save();
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
            
        }

        public virtual T Edit(T entity)
        {
            try
            {
                _entities.CreateObjectSet<T>().ApplyCurrentValues(entity);                
                Save();
                return entity;
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
           
           // _entities.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
        }

        public virtual void Save()
        {
            try
            {
                _entities.SaveChanges();
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
            
        }        
    }


}
